package com.bjb.vr.common.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bjb.vr.common.ao.OptTopicAo;
import com.bjb.vr.common.constant.AliOssConstants;
import com.bjb.vr.common.constant.ThreadLocalConstant;
import com.bjb.vr.common.dto.OptTopicConfig;
import com.bjb.vr.common.dto.OptTopicResourceRef;
import com.bjb.vr.common.dto.ResContent;
import com.bjb.vr.common.dto.ResDictionary;
import com.bjb.vr.common.mapper.OptTopicConfigMapper;
import com.bjb.vr.common.mapper.OptTopicResourceRefMapper;
import com.bjb.vr.common.mapper.ResContentMapper;
import com.bjb.vr.common.result.BaseResult;
import com.bjb.vr.common.result.CommonResult;
import com.bjb.vr.common.utils.AliyunOssUtil;
import com.bjb.vr.common.utils.ThreadLocalUtil;
import com.bjb.vr.common.vo.OptTopicVo;
import com.bjb.vr.common.vo.TopicRes;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.LongStream;

/**
 * @author admin
 * @description 针对表【opt_topic_config】的数据库操作Service实现
 * @createDate 2022-12-13 17:13:33
 */
@Service
public class OptTopicConfigService extends ServiceImpl<OptTopicConfigMapper, OptTopicConfig> {

    private static AliyunOssUtil ossUtil = null;

    static {
        ossUtil = new AliyunOssUtil.Builder().build(AliOssConstants.ENDPOINT, AliOssConstants.ACCESS_KEY_ID, AliOssConstants.ACCESS_KEY_SECRET);
    }

    @Resource
    private OptTopicConfigMapper topicConfigMapper;

    @Resource
    private OptTopicResourceRefMapper topicResourceRefMapper;

    @Resource
    private ResDictionaryService dictionaryService;

    @Resource
    private ResContentMapper contentMapper;

    public List<OptTopicVo> queryTopicList(OptTopicAo optTopicAo) {
        ThreadLocalUtil.set(ThreadLocalConstant.NO_TENANT_ID_VERIFY, true);
        List<OptTopicVo> optTopicVos = new ArrayList<>();
        LambdaQueryWrapper<OptTopicConfig> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByAsc(OptTopicConfig::getOrderNum);
        List<OptTopicConfig> optTopicConfigs = topicConfigMapper.selectList(queryWrapper);
        optTopicConfigs.stream().forEach(p -> {
            OptTopicVo optTopicVo = new OptTopicVo();
            BeanUtils.copyProperties(p, optTopicVo);
            if (optTopicAo.getNeedTopicRes()){
                // 查询资源数组
                optTopicAo.setId(p.getId());
                queryResources(optTopicAo, optTopicVo);
            }
            optTopicVos.add(optTopicVo);
        });
        return optTopicVos;
    }

    /**
     * 查询资源对象集合
     *
     * @param optTopicAo
     * @param optTopicVo
     */
    private void queryResources(OptTopicAo optTopicAo, OptTopicVo optTopicVo) {
        // 查询资源ID集合
        queryResIds(optTopicAo, optTopicVo);
        // 封装资源数据
        long[] resIds = optTopicVo.getResIds();
        List<TopicRes> topicRes = new ArrayList<>();
        for (long resId : resIds) {
            ResContent resContent = contentMapper.selectById(resId);
            TopicRes topicResObj = new TopicRes();
            topicResObj.setId(resContent.getId());
            topicResObj.setResName(resContent.getName());
            topicResObj.setResType(dictionaryService.getResDictionaryByCode(resContent.getDicTypeCode()).getDictName());
            topicResObj.setResImage(ossUtil.getFileUrl(resContent.getPreImagePath()));
            topicRes.add(topicResObj);
        }
        optTopicVo.setTopicRes(topicRes);
        optTopicVo.setResIds(null);
    }

    public OptTopicVo queryTopicOne(OptTopicAo optTopicAo) {
        ThreadLocalUtil.set(ThreadLocalConstant.NO_TENANT_ID_VERIFY, true);
        OptTopicConfig optTopicConfig = topicConfigMapper.selectById(optTopicAo.getId());
        OptTopicVo optTopicVo = new OptTopicVo();
        BeanUtils.copyProperties(optTopicConfig, optTopicVo);
        if (StringUtils.isNotBlank(optTopicVo.getPeriod())) {
            optTopicVo.setPeriodCode(dictionaryService.getDictionaryByName(optTopicVo.getPeriod()).getDictCode());
        }
        if (StringUtils.isNotBlank(optTopicVo.getLevel())) {
            optTopicVo.setLevelCode(dictionaryService.getDictionaryByName(optTopicVo.getLevel()).getDictCode());
        }
        if (StringUtils.isNotBlank(optTopicVo.getSubject())) {
            optTopicVo.setSubjectCode(dictionaryService.getDictionaryByName(optTopicVo.getSubject()).getDictCode());
        }
        if (StringUtils.isNotBlank(optTopicVo.getClassClassify())) {
            optTopicVo.setClassClassifyCode(dictionaryService.getDictionaryByName(optTopicVo.getClassClassify()).getDictCode());
        }
        if (StringUtils.isNotBlank(optTopicVo.getThemeName())) {
            optTopicVo.setThemeCode(dictionaryService.getDictionaryByName(optTopicVo.getThemeName()).getDictCode());
        }
        // 查询资源ID数组
        queryResIds(optTopicAo, optTopicVo);
        return optTopicVo;
    }

    /**
     * 查询资源ID集合
     *
     * @param optTopicAo
     * @param optTopicVo
     */
    private void queryResIds(OptTopicAo optTopicAo, OptTopicVo optTopicVo) {
        LambdaQueryWrapper<OptTopicResourceRef> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Objects.nonNull(optTopicAo.getId()), OptTopicResourceRef::getTopicId, optTopicAo.getId());
        List<OptTopicResourceRef> topicResourceRefs = topicResourceRefMapper.selectList(queryWrapper);
        long[] resIds = topicResourceRefs.stream().flatMapToLong(refs -> LongStream.of(refs.getResId())).toArray();
        optTopicVo.setResIds(resIds);
    }

    public BaseResult addTopic(OptTopicAo optTopicAo) {
        ThreadLocalUtil.set(ThreadLocalConstant.NO_TENANT_ID_VERIFY, true);
        // 判断是否超限制
        List<OptTopicConfig> optTopicConfigs = topicConfigMapper.selectList(new LambdaQueryWrapper<>());
        if (optTopicConfigs.size() >= 10) {
            log.error("专题数量超过限制【10个】");
            return CommonResult.Fail("专题数量超过限制【10个】");
        }

        try {
            // 1、保存专题数据
            OptTopicConfig optTopicConfig = new OptTopicConfig();
            BeanUtils.copyProperties(optTopicAo, optTopicConfig);

            // 设置资源的属性
            if (optTopicConfigs.size() > 0) {
                Integer orderNum = optTopicConfigs.stream().max(Comparator.comparing(OptTopicConfig::getOrderNum)).get().getOrderNum();
                optTopicConfig.setOrderNum(orderNum + 1);
            }
            exchangeDictValue(optTopicAo, optTopicConfig);
            topicConfigMapper.insert(optTopicConfig);

            // 2、保存专题和资源关联数据
            for (Long resId : optTopicAo.getResIds()) {
                OptTopicResourceRef topicResourceRef = new OptTopicResourceRef();
                topicResourceRef.setTopicId(optTopicConfig.getId());
                topicResourceRef.setResId(resId);
                topicResourceRefMapper.insert(topicResourceRef);
            }
            return CommonResult.Ok();
        } catch (Exception e) {
            log.error(e.getMessage());
            return CommonResult.Fail();
        }
    }

    /**
     * 设置字典值
     *
     * @param optTopicAo
     * @param topicConfig
     */
    private void exchangeDictValue(OptTopicAo optTopicAo, OptTopicConfig topicConfig) {
        // 清空数据
        topicConfig.setThemeName(null);
        topicConfig.setPeriod(null);
        topicConfig.setLevel(null);
        topicConfig.setSubject(null);
        topicConfig.setClassClassify(null);
        // 封装数据
        String periodCode = optTopicAo.getPeriod();
        if (StringUtils.isNotBlank(periodCode)) {
            ResDictionary dictionary = dictionaryService.getResDictionaryByCode(periodCode);
            topicConfig.setPeriod(dictionary.getDictName());
        }
        String subjectCode = optTopicAo.getSubject();
        if (StringUtils.isNotBlank(periodCode)) {
            ResDictionary dictionary = dictionaryService.getResDictionaryByCode(subjectCode);
            topicConfig.setSubject(dictionary.getDictName());
        }
        String themeCode = optTopicAo.getThemeCode();
        if (StringUtils.isNotBlank(themeCode)) {
            ResDictionary dictionary = dictionaryService.getResDictionaryByCode(themeCode);
            topicConfig.setThemeName(dictionary.getDictName());
        }
        String classClassifyCode = optTopicAo.getClassClassify();
        if (StringUtils.isNotBlank(classClassifyCode)) {
            ResDictionary dictionary = dictionaryService.getResDictionaryByCode(optTopicAo.getClassClassify());
            topicConfig.setClassClassify(dictionary.getDictName());
        }
        String classClassify = optTopicAo.getClassClassify();
        if (StringUtils.isNotBlank(classClassify)) {
            ResDictionary dictionary = dictionaryService.getResDictionaryByCode(classClassify);
            topicConfig.setClassClassify(dictionary.getDictName());
        }
    }

    public BaseResult editTopic(OptTopicAo optTopicAo) {
        ThreadLocalUtil.set(ThreadLocalConstant.NO_TENANT_ID_VERIFY, true);
        try {
            OptTopicConfig optTopicConfig = new OptTopicConfig();
            BeanUtils.copyProperties(optTopicAo, optTopicConfig);
            if (!optTopicAo.getChangeOrder()) {
                exchangeDictValue(optTopicAo, optTopicConfig);
                topicConfigMapper.updateById(optTopicConfig);
                // 更新关联表数据
                if (Objects.nonNull(optTopicAo.getResIds())) {
                    // 先删除，后新增
                    LambdaQueryWrapper<OptTopicResourceRef> queryWrapper = new LambdaQueryWrapper();
                    queryWrapper.eq(OptTopicResourceRef::getTopicId, optTopicAo.getId());
                    topicResourceRefMapper.delete(queryWrapper);
                    for (Long resId : optTopicAo.getResIds()) {
                        OptTopicResourceRef topicResourceRef = new OptTopicResourceRef();
                        topicResourceRef.setTopicId(optTopicConfig.getId());
                        topicResourceRef.setResId(resId);
                        topicResourceRefMapper.insert(topicResourceRef);
                    }
                }
                return CommonResult.Ok();
            } else {
                Integer originOrder = null;
                Integer targetOrder = null;
                OptTopicConfig originObject = topicConfigMapper.selectById(optTopicAo.getOriginId());
                OptTopicConfig targetObject = topicConfigMapper.selectById(optTopicAo.getTargetId());
                originOrder = originObject.getOrderNum();
                targetOrder = targetObject.getOrderNum();
                originObject.setOrderNum(targetOrder);
                targetObject.setOrderNum(originOrder);
                topicConfigMapper.updateById(originObject);
                topicConfigMapper.updateById(targetObject);
            }
            return CommonResult.Ok();
        } catch (Exception e) {
            log.error(e.getMessage());
            return CommonResult.Fail();
        }
    }

    public BaseResult deleteTopic(OptTopicAo optTopicAo) {
        ThreadLocalUtil.set(ThreadLocalConstant.NO_TENANT_ID_VERIFY, true);
        try {
            topicConfigMapper.deleteById(optTopicAo.getId());
            LambdaQueryWrapper<OptTopicResourceRef> queryWrapper = new LambdaQueryWrapper();
            queryWrapper.eq(OptTopicResourceRef::getTopicId, optTopicAo.getId());
            topicResourceRefMapper.delete(queryWrapper);
            return CommonResult.Ok();
        } catch (Exception e) {
            log.error(e.getMessage());
            return CommonResult.Fail();
        }
    }
}




